package com.miyu.system.service.sys.impl;


import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONReader;
import com.miyu.common.pojo.system.SysLoginLog;
import com.miyu.common.utils.commonUtils.IpUtils;
import com.miyu.common.utils.commonUtils.Rediscache;
import com.miyu.common.utils.taskJob.RedisTaskCahe;
import com.miyu.system.dao.system.SysUserDao;
import com.miyu.system.service.sys.UserLoginService;
import com.miyu.system.utils.enumeration.LoginEnum;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * 用户登录服务impl
 *
 * @author longm
 * @date 2022/10/08
 */
@Service
public class UserLoginServiceImpl implements UserLoginService {

    @Resource
    private SysUserDao userDao;
    static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(15, new BasicThreadFactory.Builder()
            .namingPattern("login-log-%d").daemon(true).build());
    /**
     * 用户登录
     * 登录校验
     * @param user 用户
     * @return {@link JSONObject}
     */
    @Override
    public JSONObject userLogin(JSONObject user) {
        JSONObject rs = new JSONObject();
        String checkCode = user.getString("checkCode").toLowerCase();
        String LoginName = user.getString("LoginName");
        String password = user.getString("userPassword");
        String loginIp = IpUtils.getIpAddr();
        //记住我
        String remember = user.getString("remember");
        SysLoginLog loginLog = new SysLoginLog();
        //登录日志缓存记录

        /** 操作IP*/
        loginLog.setOperateIp(loginIp);
        /** ip归属地运营商*/
        loginLog.setIpAddress(IpUtils.IpAddress(IpUtils.search(loginIp),4));
        /** 登录账户*/
        loginLog.setOperateAccount(LoginName);
        /*操作状态*/
        //判断验证码是否正确
        Object o = Rediscache.get(1, "checkImg:" + loginIp);
        if(o!=null) {
            if(!checkCode.equals(o.toString().toLowerCase())) {
                loginLog.setCode(LoginEnum.CODE_ERROR.getCode());
                loginLog.setMsg(LoginEnum.CODE_ERROR.getMsg());
                loginLog.setStatus(LoginEnum.CODE_ERROR.getStatus());
                executorService.submit(new RedisTaskCahe(1,1,"log:login-log",JSONObject.parse(JSONObject.toJSONString(loginLog), JSONReader.Feature.IgnoreSetNullValue)));
                return  LoginEnum.getInfoByCode("1002");
            }
        }else{
            loginLog.setCode(LoginEnum.CODE_REFRESH.getCode());
            loginLog.setMsg(LoginEnum.CODE_REFRESH.getMsg());
            loginLog.setStatus(LoginEnum.CODE_REFRESH.getStatus());
            executorService.submit(new RedisTaskCahe(1,1,"log:login-log",JSONObject.parse(JSONObject.toJSONString(loginLog), JSONReader.Feature.IgnoreSetNullValue)));
            return  LoginEnum.getInfoByCode("1003");
        }
        //校验邮箱 密码是否正确 正确登录系统 获取菜单权限路由
        JSONObject userInfo = getUserInfo(LoginName,password);
        if(userInfo.isEmpty()){
            loginLog.setCode(LoginEnum.LOGIN_ERROR.getCode());
            loginLog.setMsg(LoginEnum.LOGIN_ERROR.getMsg());
            loginLog.setStatus(LoginEnum.LOGIN_ERROR.getStatus());
            executorService.submit(new RedisTaskCahe(1,1,"log:login-log",JSONObject.parse(JSONObject.toJSONString(loginLog), JSONReader.Feature.IgnoreSetNullValue)));
            return LoginEnum.getInfoByCode("1001");
        }else {
            //验证用户属性
             /* 已停用*/
            if(userInfo.getString("isUse").equals("0")){
                loginLog.setCode(LoginEnum.USER_USE.getCode());
                loginLog.setMsg(LoginEnum.USER_USE.getMsg());
                loginLog.setStatus(LoginEnum.USER_USE.getStatus());
                executorService.submit(new RedisTaskCahe(1,1,"log:login-log",JSONObject.parse(JSONObject.toJSONString(loginLog), JSONReader.Feature.IgnoreSetNullValue)));
                return LoginEnum.getInfoByCode("1004");
            }
            if(userInfo.getString("isStop").equals("1")){
                /* 停用*/
                loginLog.setCode(LoginEnum.USER_STOP.getCode());
                loginLog.setMsg(LoginEnum.USER_STOP.getMsg());
                loginLog.setStatus(LoginEnum.USER_STOP.getStatus());
                executorService.submit(new RedisTaskCahe(1,1,"log:login-log",JSONObject.parse(JSONObject.toJSONString(loginLog), JSONReader.Feature.IgnoreSetNullValue)));
                return LoginEnum.getInfoByCode("1005");
            }
            String userId = userInfo.getString("userId");
            SaLoginModel saLoginModel = new SaLoginModel();
            saLoginModel.setDevice("PC");
            saLoginModel.setExtra("userInfo",userInfo);
            //记住我
            if(remember.equals("1")){
                 saLoginModel.setIsLastingCookie(true);
            }else {
                saLoginModel.setIsLastingCookie(false);
            }
            StpUtil.login(userId,saLoginModel);
            /*登录人*/
            loginLog.setLoginType(saLoginModel.device);
            loginLog.setCode(LoginEnum.LOGIN_SUCCESS.getCode());
            loginLog.setMsg(LoginEnum.LOGIN_SUCCESS.getMsg());
            loginLog.setStatus(LoginEnum.LOGIN_SUCCESS.getStatus());
            executorService.submit(new RedisTaskCahe(1,1,"log:login-log",JSONObject.parse(JSONObject.toJSONString(loginLog), JSONReader.Feature.IgnoreSetNullValue)));
        }
        return LoginEnum.getInfoByCode("1000");
    }

    /**
     * 获取用户信息
     * 取数据库用户信息
     * 根据邮箱 编码或手机号登录
     * @param LoginName 登录名
     * @param password  密码
     *
     * @return {@link JSONObject}
     */
    private JSONObject getUserInfo(String LoginName, String password) {
        JSONObject userInfo = new JSONObject();
        StringBuffer sql = new StringBuffer();
        sql.append(" select * from sys_user where user_email = '").append(LoginName).append("' and user_password = '").append(password).append("' ");
        userInfo = userDao.queryJSONObjectBySql(sql.toString());
        return userInfo;
    }

    /**
     * 检查编码器
     *
     * @param ip   知识产权
     * @param code 代码
     * @return {@link String}
     */
    @Override
//    @Cacheable(cacheNames  = "checkImg#300" ,key = "#ip")
    public String  checkImg(String ip,String code) {
        Rediscache.set(1,"checkImg:"+ip,code,300);
        return code;
    }


    /**
     * 用户退出
     *
     * @return {@link JSONObject}
     */
    @Override
    public JSONObject userLoginOut() {
        System.out.println(StpUtil.isLogin());
       if (!StpUtil.isLogin()) {
           return LoginEnum.getInfoByCode("1006");
       }else{
           StpUtil.logout();
       }
        return LoginEnum.getInfoByCode("1007");
    }
}
